using System;

namespace DataBroker.Criteria
{
    /// <summary>
    /// Builds a search clause by binding various Filter objects with boolean
    /// operators.
    /// </summary>
    [Serializable]
    public class Clause 
    {

        /// <summary>
        /// Entity type for correlated queries
        /// </summary>
        private Type _entityType;

        /// <summary>
        /// Name	 of the field being searched on.
        /// </summary>
        private string         _field;

        /// <summary>
        /// Boolean for the search, i.e. And or Or.
        /// </summary>
        private Logical  _logical = Logical.And;

        /// <summary>
        /// Operator joining the field and the value in question.
        /// </summary>
        private Operator _operator      = Operator.Equal;

        /// <summary>
        /// Value to which the field should be related for this query.
        /// </summary>
        private object  _fieldValue;

        // --------------------------------------------------------- CLASS CONSTRUCTORS    

        /// <summary>
        /// Constructor. Default binding to And.
        /// </summary>
        /// <param name="criteria">Filter object to be added to binding.</param>
        public Clause(Filter criteria) 
        {
            _fieldValue = criteria;
        } // END OF CONSTRUCTOR

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="criteria">Search criteria.</param>
        /// <param name="logical">Boolean connector for binding.</param>
        public Clause(Filter criteria, Logical logical) 
        {
            _fieldValue = criteria;
            _logical = logical;
        } // END OF CONSTRUCTOR

        /// <summary>
        /// Constructor for a single search value. Operator is defaulted to Equal.
        /// </summary>
        /// <param name="field">Field to search.</param>
        /// <param name="fieldValue">Value to search.</param>
        public Clause(string field, object fieldValue) 
        {
            if (fieldValue != null)
            {
                _field = field;
                if (fieldValue is string)
                    fieldValue = ((string) fieldValue).Trim(); 
            }
            _fieldValue = fieldValue;
        } // END OF CONSTRUCTOR

		
        /// <summary>
        /// Constructor for a single search value
        /// </summary>
        /// <param name="logical">Boolean connector for search.</param>
        /// <param name="field">Field to search.</param>
        /// <param name="operator">Operator for search.</param>
        /// <param name="fieldValue">Value to search.</param>
        public Clause(Logical logical, string field, Operator @operator,
                      object fieldValue) : this(field, fieldValue)
        {
			
            _logical = logical;
            _operator = @operator;
        } // END OF CONSTRUCTOR


        /// <summary>
        /// Constructor for a single search value
        /// </summary>
        /// <param name="field">Field to search.</param>
        /// <param name="operator">Operator for search.</param>
        /// <param name="fieldValue">Value to search.</param>
        /// <param name="entityType">Type of entity for search.</param>
        public Clause(string field, Operator @operator,
                      object fieldValue, Type entityType) : this(field, fieldValue)
        {
            _entityType = entityType;
            _operator = @operator;
        } // END OF CONSTRUCTOR

        // ----------------------------------------------------------- Properties    

        /// <summary>
        /// Gets current boolean search value.
        /// </summary>
        /// <returns></returns>
        public Logical Boolean
        {
            get { return _logical; }
        }

        /// <summary>
        /// Get field for binding.
        /// </summary>
        /// <returns></returns>
        public string Field
        {
            get { return _field; }
        }

        /// <summary>
        /// Get search operator for binding.
        /// </summary>
        /// <returns></returns>
        public Operator Operator
        {
            get { return _operator; }
        }


        /// <summary>
        /// Get value for binding.
        /// </summary>
        /// <returns></returns>
        public object Value
        {
            get { return _fieldValue; }
        }

        /// <summary>
        /// Get value for Entity Type (used in correlated queries)
        /// </summary>
        /// <returns></returns>
        public Type EntityType
        {
            get { return _entityType; }
        }

        // ------------------------------------------------------------ PUBLIC METHODS
		
        /// <summary>
        /// Produces a D2Bk equals (=) comparison. 
        /// </summary>
        /// <returns>D2Bk for comparison.</returns>
 
        public override string ToString()
        {
            return _field + "=" + _fieldValue + ";";
        } // END OF tostring
    
    }
}